package br.com.univas.si5.incloud.controller;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;

import br.com.univas.si5.incloud.bi.UserBi;
import br.com.univas.si5.incloud.model.Country;
import br.com.univas.si5.incloud.model.User;
import br.com.univas.si5.incloud.model.UserType;
import br.univas.si5.incloud.exception.InCloudException;

public class UserServlet extends HttpServlet{

	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {

		String jsonText = req.getReader().readLine();
		
		System.out.println(jsonText);
		
		JSONObject jsonEntry = (JSONObject) JSONValue.parse(jsonText);
		JSONObject jsonValues = (JSONObject) jsonEntry.get("entry");
		
		System.out.println("action: " + jsonValues.get("action"));
		
		/**
		 * New Register (add User)
		 */
		if (jsonValues.get("action").equals("new")){
			
			addUser(resp, jsonValues);
			
		} else {
			
			/**
			 * Update Register (update user)
			 */
			if (jsonValues.get("action").equals("update")) {
				
				updateUser(resp, jsonValues);
				
			} else {
				
				if (jsonValues.get("action").equals("updatePassword")) {
					
					HttpSession session = req.getSession();
					if (session.getAttribute("user") != null) {
						
						User user = (User) session.getAttribute("user");
						UserBi userBi = new UserBi();
						
						//get password and generate a new MD5 of it
						String newPassword = (String) jsonValues.get("password");
						System.out.println(newPassword);
						newPassword = userBi.generateMD5(newPassword);
						
						//setPassword to new Password already converted
						user.setPassword(newPassword);
						
						userBi.updateUser(user);//updateUser with a new password
						
						returnJSON(resp, "Success updating User's password");
						
					}
				}
			}
		}
		
	}




	/**
	 * UpdateUser
	 * @param resp
	 * @param jsonValues
	 */
	private void updateUser(HttpServletResponse resp, JSONObject jsonValues) {
		User user = new User();
		user.setId(Long.parseLong((String) jsonValues.get("idUser")));
		user.setName((String) jsonValues.get("name"));
		user.setPassword((String) jsonValues.get("password"));
		user.setUsername((String) jsonValues.get("username"));
		user.setMail((String) jsonValues.get("email"));
		
		/* Country */
		Country country = new Country();
		country.setIdCountry(Long.parseLong((String) jsonValues.get("country")));
		user.setCountry(country);
		
		/* UserType */
		UserType userType = new UserType();
		userType.setIdUserType(Long.parseLong((String) jsonValues.get("accountType")));
		user.setUserType(userType);
		
		UserBi userBi = new UserBi();
		userBi.updateUser(user);
		
		returnJSON(resp, "Success updating user");
	}

	
	
	
	/**
	 * AddUser
	 * @param resp
	 * @param jsonValues
	 */
	private void addUser(HttpServletResponse resp, JSONObject jsonValues) {
		User user = new User();
		user.setName((String) jsonValues.get("name"));
		user.setPassword((String) jsonValues.get("password"));
		user.setUsername((String) jsonValues.get("username"));
		user.setMail((String) jsonValues.get("email"));
		
		/* Country */
		Country country = new Country();
		country.setIdCountry(Long.parseLong((String) jsonValues.get("country")));
		user.setCountry(country);
		
		/* UserType */
		UserType userType = new UserType();
		userType.setIdUserType(Long.parseLong((String) jsonValues.get("accountType")));
		user.setUserType(userType);
		
		UserBi userBi = new UserBi();
		userBi.addUser(user);
		
		returnJSON(resp, "Success adding a new user");//return a message
	}
	
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		
		String action = req.getParameter("action");
		String username = req.getParameter("username");
		
		UserBi userBi = new UserBi();
		
		if (action.equals("validateUsername")) {
			
			/**
			 * validateUsername
			 */
			validateUsername(resp, username, userBi); 
			
		} else {
			
			if (action.equals("getUsernameInSession")) {
				
				/**
				 * get Username in session
				 */
				getUsernameInSession(req, resp);
				
			} else {
				if (action.equals("getUsernameData")) {
					
					/**
					 * getUsernameData (to load the data in form to update a user)
					 */
					getUsernameData(req, resp);
					
				} else {
					
					if (action.equals("validateOldPassword")) {
						
						/**
						 * validate if the old Password informed by User is equal to password registered by user
						 */
						validateOldPassword(req, resp, userBi);
						
					} else {
						
						/**
						 * get Usernames to show in search form
						 */
						if (action.equals("getAllUsernameByUsername")) {
							
							System.out.println("aqui buscar o username");
							getAllUsernameByUsername(resp, username, userBi);
						}
					}
				}
			}
		}
		
	}




	private void getAllUsernameByUsername(HttpServletResponse resp,
			String username, UserBi userBi) {
		
		List<User> users = userBi.getUserByCriteria("upper(username) LIKE '%" +username.toUpperCase()+ "%'");
		
		resp.setContentType("application/json");
		resp.setHeader("Cache-Control", "nocache");
		resp.setCharacterEncoding("utf-8");
		
		PrintWriter out;
		try {
			
			//Get the Object to write the answer in JSON Format
			out = resp.getWriter();
			JSONObject answer = new JSONObject(); //Create a Object of type JSON to return a answer
			
			JSONArray arrayUsernames = new JSONArray();
			
			//Generate a array of usernames located
			for (User iter : users) {
				
				System.out.println("username: " + iter.getUsername());
				JSONObject jsonUsername = new JSONObject();
				jsonUsername.put("username", iter.getUsername());
				
				arrayUsernames.add(jsonUsername);
				
			}
			
			answer.put("usernames", arrayUsernames);
			
			out.print(answer); //print the answer
			out.flush(); //clear buffer
		} catch (IOException e) {
			e.getMessage();
		}
	}



	/**
	 * validateOldPassword
	 * @param req
	 * @param resp
	 * @param userBi
	 * @throws IOException
	 */
	private void validateOldPassword(HttpServletRequest req,
			HttpServletResponse resp, UserBi userBi) throws IOException {
		
		HttpSession session = req.getSession();
		if (session.getAttribute("user")!= null) {
			
			User user = (User) session.getAttribute("user");
			String oldPassword = req.getParameter("oldPassword");
			boolean isEqualToOldPassword = false;
			
			oldPassword = userBi.generateMD5(oldPassword);
			
			if (oldPassword.equals(user.getPassword())) {
				isEqualToOldPassword = true;
			}
			
			resp.setContentType("application/json");
			resp.setHeader("Cache-Control", "nocache");
			resp.setCharacterEncoding("utf-8");
			
			PrintWriter out = resp.getWriter();
			
			JSONObject answer = new JSONObject();
			
			answer.put("isEqual", isEqualToOldPassword);
			
			out.print(answer);//print answer
			out.flush();
			
		}
	}



	/**
	 * getUsernameData
	 * @param req
	 * @param resp
	 */
	private void getUsernameData(HttpServletRequest req,
			HttpServletResponse resp) {
		HttpSession session = req.getSession();
		if (session.getAttribute("user") != null) {
			User user = (User) session.getAttribute("user");
			
			resp.setContentType("application/json");
			resp.setHeader("Cache-Control", "nocache");
			resp.setCharacterEncoding("utf-8");
			
			PrintWriter out;
			try {
				
				//Get the Object to write the answer in JSON Format
				out = resp.getWriter();
				JSONObject answer = new JSONObject(); //Create a Object of type JSON to return a answer
				
				answer.put("name", user.getName());
				answer.put("username", user.getUsername());
				answer.put("mail", user.getMail());
				answer.put("country", user.getCountry().getIdCountry());
				answer.put("userType", user.getUserType().getIdUserType());
				answer.put("idUser", user.getIdUser());
				answer.put("password", user.getPassword());
				
				System.out.println(answer);
				out.print(answer); //print the answer
				out.flush(); //clear buffer
			} catch (IOException e) {
				e.getMessage();
			} 
		}
	}



	/**
	 * getUsernameInSession
	 * @param req
	 * @param resp
	 */
	private void getUsernameInSession(HttpServletRequest req,
			HttpServletResponse resp) {
		HttpSession session = req.getSession();
		
		resp.setContentType("application/json");
		resp.setHeader("Cache-Control", "nocache");
		resp.setCharacterEncoding("utf-8");
		
		PrintWriter out;
		
		JSONObject answer = new JSONObject(); //Create a Object of type JSON to return a answer
		
		if (session.getAttribute("user") != null) {
			User user = (User) session.getAttribute("user");
			
			
			try {
				//Get the Object to write the answer in JSON Format
				out = resp.getWriter();
				
				
				answer.put("name", user.getName());
				answer.put("username", user.getUsername());
				
				out.print(answer); //print the answer
				out.flush(); //clear buffer
			} catch (IOException e) {
				e.getMessage();
			} 
		} else {
			
			try {
				
				out = resp.getWriter();
				
				answer.put("name", null);
				answer.put("username", null);
				
				out.print(answer);
				out.flush();
				
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}



	/**
	 * validateUsername
	 * @param resp
	 * @param username
	 * @param userBi
	 */
	private void validateUsername(HttpServletResponse resp, String username,
			UserBi userBi) {
		List<User> users = userBi.getUserByCriteria("lower(username) = '" +username+ "'");
		
		resp.setContentType("application/json");
		resp.setHeader("Cache-Control", "nocache");
		resp.setCharacterEncoding("utf-8");
		
		PrintWriter out;
		try {
			
			//Get the Object to write the answer in JSON Format
			out = resp.getWriter();
			JSONObject answer = new JSONObject(); //Create a Object of type JSON to return a answer
			
			if (users.isEmpty()) {
				answer.put("isValid", true); //add the created ArrayJSon on key message to return to Javascript by AJAX
			} else {
				answer.put("isValid", false);
			}
			out.print(answer); //print the answer
			out.flush(); //clear buffer
		} catch (IOException e) {
			e.getMessage();
		}
	}
	
	
	
	/**
	 * returnJSON
	 * @param resp
	 * @param message
	 */
	private void returnJSON(HttpServletResponse resp, String message){
		
		/*
		 * Criar o objeto JSON para retornar a página inicial caso seja necessário
		 * por exemplo um erro no login
		 */
		
		resp.setContentType("application/json");
		resp.setHeader("Cache-Control", "nocache");
		resp.setCharacterEncoding("utf-8");
		
		PrintWriter out;
		try {
			
			//Get the Object to write the answer in JSON Format
			out = resp.getWriter();
			JSONObject answer = new JSONObject(); //Create a Object of type JSON to return a answer
			
			//message
			answer.put("message", message); //add the created ArrayJSon on key message to return to Javascript by AJAX
			
			out.print(answer); //print the answer
			out.flush(); //clear buffer
		} catch (IOException e) {
			e.getMessage();
		} 
		
	}
}
